#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
using namespace std;


//1.键盘终端产生信号
void handler(int signo)
{
    std::cout << "获得一个" << signo << "号信号" << std::endl;
    exit(1);
}

int main()
{
    signal(19, handler);
   
    signal(2, handler);
    while(true)
    {
        std::cout << "running...., pid : " << getpid() << std::endl;
        sleep(1);
    }
}


//2.系统调用产生信号

static void Usage(const string &proc)//使用手册 在本文件内有效
{
    cout << "\nUsage: " << proc << "-signumber process\n" << endl;
}

void handler(int signo)
{
    std::cout << "获得一个" << signo << "号信号" << std::endl;
    exit(1);
}

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(0);
    }

    int signumber = std::stoi(argv[1] + 1);
    int processpid = std::stoi(argv[2]);
    kill(processpid, signumber);
}



//3.异常

void handler(int signo)
{
    cout << "get a signo : " << signo << endl;
    sleep(1);
}

int main()
{
    signal(8, handler);
    int a = 10;
    a /= 0;
    return 0;
}


////4.由软件条件产生信号

using namespace std;
int cnt = 0;

void handler(int signo)
{
    cout << "get a signo : " << signo << " alarm : " << cnt << endl;
    sleep(1);
    exit(0);
}

int main()
{
    signal(14, handler);
    alarm(1);

    while(true)
    {
        cnt++;
    }
    return 0;
}



///// 信号集操作函数-屏蔽2号信号 
void handler(int signo)
{
    cout << "handler " << signo << endl;
}

int main()
{
    cout << "getpid: " << getpid() << endl;

    signal(2, handler);
      
    sigset_t block, oblock;
    sigemptyset(&block);
    sigemptyset(&oblock);
   // sigaddset(&block, 2); //在这里并没有设置对2号信号的屏蔽？

   for(int signo = 1; signo <= 31; signo++) sigaddset(&block, signo);//屏蔽所有信号
    sigaddset(&block, 2); 
    sigprocmask(SIG_BLOCK, &block, &oblock);
    while(true)
    {
        cout << "我已经屏蔽了所有信号！" << endl;
        sleep(1);

    }

}

///   获取pending表 

void PrintPending(const sigset_t &pending)
{
    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&pending, signo))
        {
            cout << "1";
        }
        else{
            cout << "0";
        }
    }
    cout << "\n";

}

int main()
{
    cout << "getpid: " << getpid() << endl;
    //1.屏蔽2号信号
    sigset_t set, oset;
    sigemptyset(&set);
    sigemptyset(&set);
    sigaddset(&set, 2);
    sigprocmask(SIG_BLOCK, &set, &oset);

    //2.让进程不断获取当前进程的pending
    int cnt = 0;
    sigset_t pending;
    while(true)
    {
        sigpending(&pending);
        PrintPending(pending);
        sleep(1);
        cnt++;

        if(cnt == 15)
        {
            cout << "解除对2号信号的屏蔽，2号信号准备递达" << endl;
            sigprocmask(SIG_SETMASK, &oset, nullptr);//2号信号递达后 不会再打印，进程终止了
        }
    }


    return 0;
}


//// 在信号捕捉放方法内获取当前进程的信号 
void Print(const sigset_t &pending);
void handler(int signo)
{       
    cout << "get a sig: " << signo << endl;
    while(true)
    {
        sigset_t pending;
        sigpending(&pending);
        Print(pending);
        sleep(1);
    }
    sleep(10);
}

void Print(const sigset_t &pending)
{
    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&pending, signo))
        {
            cout << "1";
        }
        else
        {
            cout << "0";

        }
    }
    cout << endl;
}


int main()
{
    cout << "pid: " << getpid() << endl; 
    struct sigaction act, oact;
    act.sa_handler = handler;

    sigemptyset(&act.sa_mask);//初始化
    sigaddset(&act.sa_mask, 3);//添加3号信号
    
    sigaction(2, &act, &oact);  

    while(true) sleep(1); 
    return 0;
}


//// 在mask中添加多个屏蔽信号 
void Print(const sigset_t &pending);
void handler(int signo)
{       
    cout << "get a sig: " << signo << endl;
    sleep(1);
    // while(true)
    // {
    //     sigset_t pending;
    //     sigpending(&pending);
    //     Print(pending);
    //     sleep(1);
    // }
    // sleep(10);
}

void Print(const sigset_t &pending)
{
    for(int signo = 31; signo > 0; signo--)
    {
        if(sigismember(&pending, signo))
        {
            cout << "1";
        }
        else
        {
            cout << "0";

        }
    }
    cout << endl;
}


int main()
{
    signal(2, handler);
    signal(3, handler);
    signal(4, handler);
    signal(5, handler);
    
    sigset_t mask, omask;
    sigemptyset(&mask);
    sigemptyset(&omask);

    sigaddset(&mask, 2);
    sigaddset(&mask, 3);
    sigaddset(&mask, 4);
    sigaddset(&mask, 5);

    sigprocmask(SIG_SETMASK, &mask, &omask);

    int cnt = 20;
    while(true)
    {
        cnt--;
        printf("cnt: %d\n", cnt);
        sleep(1);
        if(cnt == 0)
        {
            sigprocmask(SIG_SETMASK, &omask, nullptr);
            cout << "cancel 2, 3, 4, 5 block" << endl;
        }
    }
    return 0;
}


